package nosql.query;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import nosql.MysqlConnector;
import nosql.util.ComponentScore;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;

public class FilterRecommender extends Recommender {

	public FilterRecommender(MysqlConnector connector, int type) {
		super(connector, type);
	}

	@Override
	public List<ComponentScore> getScores(String[] filterProperties, JSONArray queryConditions) {
		//	parse conditions
		List<String> conditionList = new ArrayList<String>();
		JSONParser parser = new JSONParser();
		try{
			if(queryConditions != null){
				for (Object subObj : queryConditions) {
					Object parsedObj = parser.parse(subObj.toString());
					if (parsedObj instanceof JSONObject) {
						JSONObject jsonObj = (JSONObject) parsedObj;
						String name = jsonObj.get("name").toString();
						conditionList.add(name);
					}
				}
			}
		}catch(ParseException pe){
			pe.printStackTrace();
		}catch(Exception e){
			e.printStackTrace();
		}
		
		
		Set<String> candidatePropertySet = connector.getAllPropertyTableName();
		candidatePropertySet.removeAll(Arrays.asList(filterProperties));
		
		Set<String> curPropertiesSet = new HashSet<String>();
		curPropertiesSet.addAll(Arrays.asList(filterProperties));
		curPropertiesSet.addAll(conditionList);
		
		
		System.out.println("Calculate scores...");
		List<ComponentScore> scoreList = new ArrayList<ComponentScore>();
		
		try{
//			String prepEStr = "SELECT sum(occurrence) FROM `*` WHERE (firstProperty=? AND secondProperty=? OR firstProperty=? AND secondProperty=?) AND type=" + type + ";";
			String prepEStr = "SELECT sum(occurrence) FROM `*` WHERE (firstProperty=? AND secondProperty=? OR firstProperty=? AND secondProperty=?);";
//			String prepVStr = "SELECT sum(occurrence) FROM `*` WHERE (firstProperty=? OR secondProperty=?) AND type=" + type + ";";
			String prepVStr = "SELECT sum(occurrence) FROM `*` WHERE (firstProperty=? OR secondProperty=?);";
			
			PreparedStatement prepEStmt = connector.getConnection().prepareStatement(prepEStr);
			PreparedStatement prepVStmt = connector.getConnection().prepareStatement(prepVStr);
			
			for(String filter : candidatePropertySet){
				double score = 1.0;
				for(String curProperty : curPropertiesSet){
					//	get E weight
					prepEStmt.setString(1, filter);
					prepEStmt.setString(2, curProperty);
					prepEStmt.setString(3, curProperty);
					prepEStmt.setString(4, filter);
					ResultSet rsE = prepEStmt.executeQuery();
					prepEStmt.clearParameters();
					rsE.next();
					int weightE = rsE.getInt(1);
					
					//	get V weight
					prepVStmt.setString(1, curProperty);
					prepVStmt.setString(2, curProperty);
					ResultSet rsV = prepVStmt.executeQuery();
					prepVStmt.clearParameters();
					rsV.next();
					int weightV = rsV.getInt(1);
					
					if(weightV != 0){
						score *= (((double)weightE)/weightV + 1);
					}
				}
				scoreList.add(new ComponentScore(filter, score));
			}
		} catch(SQLException sqle){
			sqle.printStackTrace();
		} catch(Exception e){
			e.printStackTrace();
		}
		
//		for(ComponentScore score : scoreList){
//			System.out.println(score);
//		}
//		System.out.println("Recommend finished.");
		return scoreList;
	}

}
